package com.uaa.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;


/**
 * 认证服务配置类
 *
 * @Author Daft_V
 * @Date 2022/5/15 17:04
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {

    @Value("${oauth.redirectUrl}")
    String redirectUrl;

    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private AuthorizationCodeServices authorizationCodeServices;
    @Qualifier("tokenServices")
    @Autowired
    private AuthorizationServerTokenServices authorizationServerTokenServices;
    @Qualifier("myClientDetailsService")
    @Autowired
    private ClientDetailsService clientDetailsService;




    /**
     * 配置客户端详情
     *
     * @param clients 客户端
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // 使用数据库存储
        clients.withClientDetails(clientDetailsService);

        //使用内存存储
//        clients.inMemory()
//                //客户端id
//                .withClient("c1")
//                //客户端密钥
//                .secret(new BCryptPasswordEncoder().encode("aabbcc"))
//                //可以访问的资源列表
//                .resourceIds("res1")
//                //允许客户端以哪种方式获取令牌
//                .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
//                //允许授权的范围
//                .scopes("all")
//                //false跳转到授权页面,true就不会跳转
//                .autoApprove(false)
//                //验证回调地址
//                .redirectUris(redirectUrl);
    }

    /**
     * 配置令牌访问端点和令牌服务
     *
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                // 认证管理器
                .authenticationManager(authenticationManager)
                //授权码服务
                .authorizationCodeServices(authorizationCodeServices)
                //令牌服务
                .tokenServices(authorizationServerTokenServices)
                //允许访问令牌端点的请求方式
                .allowedTokenEndpointRequestMethods(HttpMethod.POST);
    }

    /**
     * 配置认证服务的安全约束
     *
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                // 开启/oauth/token_key验证端口无权限访问
                .tokenKeyAccess("permitAll()")
                // 开启/oauth/check_token验证端口无权限访问
                .checkTokenAccess("permitAll()")
                // 允许表单认证
                .allowFormAuthenticationForClients();
    }
}
